﻿using System;
using System.Collections;
using System.Collections.Generic;
using GeoAPI.Geometries;
using NetTopologySuite.Mathematics;

namespace NetTopologySuite.Geometries
{
	public static class CoordinateArrays
	{
		public static bool IsRing(Coordinate[] pts)
		{
			return pts.Length >= 4 && pts[0].Equals2D(pts[pts.Length - 1]);
		}

		public static Coordinate PointNotInList(Coordinate[] testPts, Coordinate[] pts)
		{
			foreach (Coordinate coordinate in testPts)
			{
				if (CoordinateArrays.IndexOf(coordinate, pts) < 0)
				{
					return coordinate;
				}
			}
			return null;
		}

		public static int Compare(Coordinate[] pts1, Coordinate[] pts2)
		{
			int num = 0;
			while (num < pts1.Length && num < pts2.Length)
			{
				int num2 = pts1[num].CompareTo(pts2[num]);
				if (num2 != 0)
				{
					return num2;
				}
				num++;
			}
			if (num < pts2.Length)
			{
				return -1;
			}
			if (num < pts1.Length)
			{
				return 1;
			}
			return 0;
		}

		public static int IncreasingDirection(Coordinate[] pts)
		{
			for (int i = 0; i < pts.Length / 2; i++)
			{
				int num = pts.Length - 1 - i;
				int num2 = pts[i].CompareTo(pts[num]);
				if (num2 != 0)
				{
					return num2;
				}
			}
			return 1;
		}

		private static bool IsEqualReversed(Coordinate[] pts1, Coordinate[] pts2)
		{
			for (int i = 0; i < pts1.Length; i++)
			{
				Coordinate coordinate = pts1[i];
				Coordinate other = pts2[pts1.Length - i - 1];
				if (coordinate.CompareTo(other) != 0)
				{
					return false;
				}
			}
			return true;
		}

		public static Coordinate[] CopyDeep(Coordinate[] coordinates)
		{
			Coordinate[] array = new Coordinate[coordinates.Length];
			for (int i = 0; i < coordinates.Length; i++)
			{
				Coordinate coordinate = new Coordinate(coordinates[i]);
				array[i] = coordinate;
			}
			return array;
		}

		public static void CopyDeep(Coordinate[] src, int srcStart, Coordinate[] dest, int destStart, int length)
		{
			for (int i = 0; i < length; i++)
			{
				Coordinate coordinate = new Coordinate(src[srcStart + i]);
				dest[destStart + i] = coordinate;
			}
		}

		[Obsolete("Use generic method instead")]
		public static Coordinate[] ToCoordinateArray(ICollection coordList)
		{
			List<Coordinate> list = new List<Coordinate>(coordList.Count);
			foreach (object obj in coordList)
			{
				Coordinate item = (Coordinate)obj;
				list.Add(item);
			}
			return list.ToArray();
		}

		public static Coordinate[] ToCoordinateArray(ICollection<Coordinate> coordList)
		{
			List<Coordinate> list = new List<Coordinate>(coordList.Count);
			foreach (Coordinate item in coordList)
			{
				list.Add(item);
			}
			return list.ToArray();
		}

		public static bool HasRepeatedPoints(Coordinate[] coord)
		{
			for (int i = 1; i < coord.Length; i++)
			{
				Coordinate coordinate = coord[i - 1];
				Coordinate other = coord[i];
				if (coordinate.Equals(other))
				{
					return true;
				}
			}
			return false;
		}

		public static Coordinate[] AtLeastNCoordinatesOrNothing(int n, Coordinate[] c)
		{
			if (c.Length < n)
			{
				return new Coordinate[0];
			}
			return c;
		}

		public static Coordinate[] RemoveRepeatedPoints(Coordinate[] coord)
		{
			if (!CoordinateArrays.HasRepeatedPoints(coord))
			{
				return coord;
			}
			return new CoordinateList(coord, false).ToCoordinateArray();
		}

		public static Coordinate[] RemoveNull(Coordinate[] coord)
		{
			List<Coordinate> list = new List<Coordinate>(coord.Length);
			foreach (Coordinate coordinate in coord)
			{
				if (coordinate != null)
				{
					list.Add(coordinate);
				}
			}
			return list.ToArray();
		}

		public static void Reverse(Coordinate[] coord)
		{
			Array.Reverse(coord);
		}

		public static bool Equals(Coordinate[] coord1, Coordinate[] coord2)
		{
			if (coord1 == coord2)
			{
				return true;
			}
			if (coord1 == null || coord2 == null)
			{
				return false;
			}
			if (coord1.Length != coord2.Length)
			{
				return false;
			}
			for (int i = 0; i < coord1.Length; i++)
			{
				if (!coord1[i].Equals(coord2[i]))
				{
					return false;
				}
			}
			return true;
		}

		public static bool Equals(Coordinate[] coord1, Coordinate[] coord2, IComparer<Coordinate[]> coordinateComparer)
		{
			return coord1 == coord2 || (coord1 != null && coord2 != null && coord1.Length == coord2.Length && coordinateComparer.Compare(coord1, coord2) == 0);
		}

		public static Coordinate MinCoordinate(Coordinate[] coordinates)
		{
			Coordinate coordinate = null;
			for (int i = 0; i < coordinates.Length; i++)
			{
				if (coordinate == null || coordinate.CompareTo(coordinates[i]) > 0)
				{
					coordinate = coordinates[i];
				}
			}
			return coordinate;
		}

		public static void Scroll(Coordinate[] coordinates, Coordinate firstCoordinate)
		{
			int num = CoordinateArrays.IndexOf(firstCoordinate, coordinates);
			if (num < 0)
			{
				return;
			}
			Coordinate[] array = new Coordinate[coordinates.Length];
			Array.Copy(coordinates, num, array, 0, coordinates.Length - num);
			Array.Copy(coordinates, 0, array, coordinates.Length - num, num);
			Array.Copy(array, 0, coordinates, 0, coordinates.Length);
		}

		public static int IndexOf(Coordinate coordinate, Coordinate[] coordinates)
		{
			for (int i = 0; i < coordinates.Length; i++)
			{
				Coordinate other = coordinates[i];
				if (coordinate.Equals(other))
				{
					return i;
				}
			}
			return -1;
		}

		public static Coordinate[] Extract(Coordinate[] pts, int start, int end)
		{
			start = MathUtil.Clamp(start, 0, pts.Length);
			end = MathUtil.Clamp(end, -1, pts.Length);
			int num = end - start + 1;
			if (end < 0)
			{
				num = 0;
			}
			if (start >= pts.Length)
			{
				num = 0;
			}
			if (end < start)
			{
				num = 0;
			}
			Coordinate[] array = new Coordinate[num];
			if (num == 0)
			{
				return array;
			}
			Array.Copy(pts, start, array, 0, num);
			return array;
		}

		public static Envelope Envelope(Coordinate[] coordinates)
		{
			Envelope envelope = new Envelope();
			foreach (Coordinate p in coordinates)
			{
				envelope.ExpandToInclude(p);
			}
			return envelope;
		}

		public static Coordinate[] Intersection(Coordinate[] coordinates, Envelope env)
		{
			CoordinateList coordinateList = new CoordinateList();
			foreach (Coordinate coordinate in coordinates)
			{
				if (env.Intersects(coordinate))
				{
					coordinateList.Add(coordinate, true);
				}
			}
			return coordinateList.ToCoordinateArray();
		}

		public class ForwardComparator : IComparer<Coordinate[]>
		{
			public int Compare(Coordinate[] pts1, Coordinate[] pts2)
			{
				return CoordinateArrays.Compare(pts1, pts2);
			}
		}

		public class BidirectionalComparator : IComparer<Coordinate[]>
		{
			public int Compare(Coordinate[] pts1, Coordinate[] pts2)
			{
				if (pts1.Length < pts2.Length)
				{
					return -1;
				}
				if (pts1.Length > pts2.Length)
				{
					return 1;
				}
				if (pts1.Length == 0)
				{
					return 0;
				}
				int result = CoordinateArrays.Compare(pts1, pts2);
				if (CoordinateArrays.IsEqualReversed(pts1, pts2))
				{
					return 0;
				}
				return result;
			}

			public int OldCompare(Coordinate[] pts1, Coordinate[] pts2)
			{
				if (pts1.Length < pts2.Length)
				{
					return -1;
				}
				if (pts1.Length > pts2.Length)
				{
					return 1;
				}
				if (pts1.Length == 0)
				{
					return 0;
				}
				int num = CoordinateArrays.IncreasingDirection(pts1);
				int num2 = CoordinateArrays.IncreasingDirection(pts2);
				int num3 = (num > 0) ? 0 : (pts1.Length - 1);
				int num4 = (num2 > 0) ? 0 : (pts1.Length - 1);
				for (int i = 0; i < pts1.Length; i++)
				{
					int num5 = pts1[num3].CompareTo(pts2[num4]);
					if (num5 != 0)
					{
						return num5;
					}
					num3 += num;
					num4 += num2;
				}
				return 0;
			}
		}
	}
}
